﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MegavaniaX.Rendering;
using MegavaniaX.Messaging.Events;
using MegavaniaX.World;
namespace MegavaniaX
{    
    /// <summary>
    /// Class for the eye block dude.
    /// </summary>
    public class EyeBlock : Actor, ITakesDamage, IHurtsPlayer, IAIActor
    {
        #region Animations
        private Animation a_idle;
        private Animation a_moveStart;
        private Animation a_moveEnd;
        #endregion

        private List<TimedAINode> _nodes;
        private DateTime timeStartedAtCurrentNode = DateTime.MinValue;
        private int _currentNodeIndex;
        private bool _isMoving = false;
        private float _speed = 0.0005f;

        public EyeBlock(string id) : base(id)
        {
            IsAffectedByWalls = false;
            IsAffectedByGravity = false;
            IsDamagingToPlayer = true;
            IsTakesDamage = true;
            IsHurtsPlayer = true;
            IsAIActor = true;

            _nodes = new List<TimedAINode>();

            // animation setup
            a_idle = AnimationManager.MakeAnimation("eyeblock_idle");
            a_moveStart = AnimationManager.MakeAnimation("eyeblock_startmove");
            a_moveEnd = AnimationManager.MakeAnimation("eyeblock_endmove");

            CurrentAnimation = a_idle;
            Height = 16;
            Width = 16;
        }

        public override MegavaniaSprite CurrentSprite()
        {
            return CurrentAnimation.CurrentSprite();
        }

        #region ITakesDamage

        private int _health = 5;
        /// <summary>
        /// Total health of the actor
        /// </summary>
        public int TotalHealth { get { return _health; } private set { _health = value; } }

        /// <summary>
        /// Invincibility period after taking damage.
        /// </summary>
        public int InvincibilityPeriod { get { return 0; } }

        public void TakeDamage (IDealsDamage damager)
        {
            TotalHealth--;
            if (TotalHealth <= 0)
            {
                MessagingSystem.DispatchEvent(new DespawnActorEvent(MegavaniaEventType.DespawnActor, this));
            }
        }

        /// <summary>
        /// sets the nodes for this eye block
        /// </summary>
        /// <param name="nodes"></param>
        public void SetNodes(params TimedAINode[] nodes)
        {
            for (int i = 0; i < nodes.Length; i++)
                _nodes.Add(nodes[i]);
        }

        /// <summary>
        /// AI update function
        /// </summary>
        /// <param name="nothing">Don't need any parameters!</param>
        public void AIUpdate(dynamic nothing)
        {
            if (_nodes.Count == 0)
            {
                // MegavaniaX.logger.Warn("Eyeblock " + this.ActorID + " did not have any nodes for an AI update!");
                return;
            }
            if (_nodes.Count == 1) // no movement, since there's only 1 node..
                return;

            if (!_isMoving)
            {
                if (timeStartedAtCurrentNode == DateTime.MinValue) // first ai update
                {
                    timeStartedAtCurrentNode = DateTime.Now;
                    _currentNodeIndex = 0;
                }
                TimeSpan timeAtNode = DateTime.Now - timeStartedAtCurrentNode;
                // if we've been at the current node long enough, start moving
                if (timeAtNode >= _nodes[_currentNodeIndex].Time)
                {
                    MegavaniaX.logger.Debug("Moving from " + _currentNodeIndex);
                    AINode currNode = _nodes[_currentNodeIndex].Node;                    
                    _currentNodeIndex++;
                    if (_currentNodeIndex >= _nodes.Count)
                        _currentNodeIndex = 0;
                    AINode nextNode = _nodes[_currentNodeIndex].Node;
                    MegavaniaX.logger.Debug("Next node is at " + nextNode.CenterX + "," + nextNode.CenterY);
                    if (currNode.Top == nextNode.Top && currNode.Left == nextNode.Left) // same node I guess?
                    {
                        return;
                    }
                    else
                    {
                        _isMoving = true;
                        this.velocity = (nextNode.position - this.position) * this._speed;
                        MegavaniaX.logger.Debug(this.ActorID + " new velocity is " + this.velocity.ToString());
                        CurrentAnimation = a_moveStart;
                    }
                }
            }
            else // check if we've hit or passed our target
            {
                AINode targetNode = _nodes[_currentNodeIndex].Node;
                if ((this.velocity.X > 0.0f && this.Left > targetNode.Left) || (this.velocity.X < 0.0f && this.Right < targetNode.Right))
                {
                    _isMoving = false;
                    this.velocity = Microsoft.Xna.Framework.Vector2.Zero;
                    this.position = _nodes[_currentNodeIndex].Node.position;
                    CurrentAnimation = a_moveEnd;
                }
            }
        }

        #endregion

        #region IHurtsPlayer

        public int BaseDamageToPlayer { get { return 1; } }

        #endregion

    }
}
